package com.tedu.api.map;

import org.junit.Test;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.function.BiConsumer;

/**
 * 包位置：java.util
 * Map顶级映射接口
 * 作用：一个对象由两个元素构成：分别键：Key与值：Value;
 * 保存一个元素：Key---value【保存一对：两个对象】
 * 用途：通常与数据库搭配使用
 * 特点：键：无序、无下标、不可重复，实际存在HashSet
 *      值：存泛型约束的类型，可以重复，实际存Collection
 *      Map 接口对象创建---实现类；
 *      HashMap:【常用：HashMap的方法与Map方法类似】由键值对组成，使用哈希算法实现
 *      键与值可以为null，键中只允许一个null！
 *
 *      LinkedHashMap:【不常用：方法与HashMap类似】两端插入增加效率高
 *      TreeMap：【不用】【算法：红黑树】性能：效率较低
 *      HashTable:【不用】jdk1.0版本，
 *      ConcurrentHashMap:【常用】多线程
 */
//map (key键,value值)的形式来进行存值的  一组entry map可存多个entry  entry是一组对象是内部接口类
public class MapAPI {
    @Test
    public void testMap(){
        //创建Map映射集合接口
        Map<Object,String> map=new HashMap<>();
        /**
         * put(键K，值V)   返回值：V  value---实际Collection
         * 作用：映射集合存入一队元素：键与值
         */
        map.put("西游记","孙悟空");//Key键：Set集合：无序、无下标、唯一

        map.put("红楼梦","林黛玉");//Key值一致，进行覆盖
        map.put("水浒传","宋公明");
        map.put("三国志","诸葛亮");
        map.put("红楼梦","贾宝玉");
        map.put(null,"无名氏");
        System.out.println("Map集合"+map);
        //需求 ：获取一些元素中值：”林黛玉“  get(键) 通过键找到值
        String lin=map.get("红楼梦");
        System.out.println("通过键找值："+lin);
        //没有这个键，自动按照Collection对象，补对象默认：null
        System.out.println("通过键找值【键不存在】："+map.get("三国"));


        //删除元素中：键    remove(Key)  返回值：V  value Collection
        map.remove("红楼梦");
        System.out.println("Map集合："+map);


        //size()  获取映射集合的元素个数
        System.out.println("Map集合元素总数："+map.size());

        //containsKey()   判断键是否存在  返回值：boolean
        //containsValue(Value) 判断值是否存在  返回值：boolean
        //1.键是否存在
        boolean b=map.containsKey("三国志");//存在返回true 不存在返回false
        System.out.println("判断是否存在："+b);
        //2.值是否存在
        boolean v=map.containsValue("宋公明");
        System.out.println("判断值是否存在："+v);
    }
    /**
     * Map映射集合当中：一组键值对存入【一组元素：Entry】
     * 遍历映射集合：遍历所有的键，遍历所有的值，遍历所有的Entry
     * keySet：获取集合中所有的键
     * values：获取集合当中所有的值
     * entrySet:获取集合中所有的[entry:键与值]
     *
     */
    @Test
    public void testMaps(){
        Map<Object,String>map=new HashMap<>();//<泛型，泛型>
        map.put("蓝色监狱","洁世一");
        map.put("死亡笔记","夜神月");
        map.put("盗墓笔记","张起灵 ");
        map.put("排球少年","日向翔阳");
        //keySet()  获取所有键
        Set<Object> set=map.keySet();//为了获取准确 加了<Object>  光标
        //遍历所有的键：增强for
        for(Object o:set){//从set集合中获取所有的键
            System.out.println("获取所有的键："+o);

        }
        //2.values()  获取所有的值
       Collection<String> c =map.values();  //光标
        //遍历所有值：增强for
        for(String s:c){
            System.out.println("获取所有值："+c);
        }
        //3.entrySet()  获取所有的Entry键值
        //返回值:Set<Map.Entry<K,V>>
        //Entry类型：Map.Entry<K,V>
        //Entry存在值的对象---Map增加一个针对"键值对"的对象
        //Map.Entry   【Map接口.Entry内部接口对象】
        Set<Map.Entry<Object,String>> sets=map.entrySet();
                //获取所有【entry】键值对
        for(Map.Entry<Object,String>s:sets){
           // System.out.println("所有entry："+s);
            //Entry中Key与Value方法：getKey()  getValue()
            Object key=s.getKey();


        }
    }
    /**
     * forEach(new BiConsumer())
     * BiConsumer  接口   ----封装了Entry对象的键与值
     * 作用：遍历出集合中所有的entry【键与值】
     */
    @Test
    public void testForEach(){
        Map<Object,String>map=new HashMap<>();
        map.put("唐山","棋子烧饼");
        map.put("邢台","酸枣汁");
        map.put("邯郸","二宝烧鸡");
        map.put("沧州","火锅鸡");
        //forEach(接口)遍历映射集合：键与值
        map.forEach(new BiConsumer<Object, String>() {

            public void accept(Object o, String s) {
                System.out.println("所有的键："+o);
                System.out.println("所有的值："+s);
            }
        });
    }
    /**
     * HashMap中独有方法
     * putIfAbsent
     * 作用：存一组entry，先判断指定的键是否存在，不存在将键值插入
     *                                      存在值不插入
     *
     */
    @Test
    public void testHashMap(){
        Map<Object,String>map=new HashMap<>();
        map.put("唐山","棋子烧饼");
        map.put("邢台","酸枣汁");
        map.put("邯郸","二宝烧鸡");
        map.put("沧州","火锅鸡");
        map.putIfAbsent("石家庄","八大碗");
        map.putIfAbsent("唐山","麻糖");//相同键，不插入
        System.out.println("HashMap:"+map);
    }
}
